package com.mryang.hds.service.impl;

import com.mryang.hds.configs.AppException;
import com.mryang.hds.entity.*;
import com.mryang.hds.mapper.*;
import com.mryang.hds.service.ManageService;
import com.mryang.hds.utils.DateUtil;
import com.mryang.hds.utils.ResultCode;
import org.apache.ibatis.annotations.Param;
import org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.unit.DataUnit;

import javax.annotation.Resource;
import javax.xml.crypto.Data;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * @author Genius
 * @version 1.0.0
 * @ClassName ManageServiceImpl.java
 * @Description TODO
 * @createTime 2023年01月26日 12:55:00
 */
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
@Service
public class ManageServiceImpl implements ManageService {
    @Resource
    private ManageMapper manageMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private PunchRecordMapper punchRecordMapper;

    @Resource
    private PunchInfoMapper punchInfoMapper;

    @Resource
    private NeedMapper needMapper;

    @Resource
    private NotifyMapper notifyMapper;

    @Resource
    private TripInfoMapper tripInfoMapper;

    @Resource
    private RecoveredMapper recoveredMapper;


    @Override
    public List<User> getUser(User token ) {
        List<User> list = manageMapper.getUser(token);
        return list;
    }

    @Override
    public List<User> getDocterUser() {
        try {
            List<User> list = manageMapper.getDocterUser();
            return list;
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.MANAGE_USER_FAIL);
        }

    }

    @Override
    public List<User> searchUser(String name, Integer gender, Integer age, String address,User token ) {
        try {
            List<User> users = null;

            if (gender==null || gender == 2){
                users = manageMapper.searchUser(name,null,age,address,token );
            }else {
                users = manageMapper.searchUser(name,gender,age,address,token );
            }

            return users;
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.MANAGE_USER_FAIL);
        }


    }

    @Override
    public List<User> searchDocterUser(String name, Integer gender, Integer age, String address) {
        try {
            List<User> users = null;

            if (gender==null || gender == 2){
                users = manageMapper.searchDocterUser(name,null,age,address);
            }else {
                users = manageMapper.searchDocterUser(name,gender,age,address);
            }

            return users;
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.MANAGE_USER_FAIL);
        }
    }

    @Override
    public List<User> searchPunch(String name, Integer status, Integer punchInfo, String address,User token) {
        try {
            return manageMapper.searchPunchUser(name,status,punchInfo,address,token);
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.MANAGE_USER_FAIL);
        }
    }

    @Override
    public List<User> getUserNoPunch(User token) {
        try {
            List<User> list = manageMapper.getUserNoPunch(token);
            return list;
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.MANAGE_USER_FAIL);
        }
    }

    @Transactional
    @Override
    public void delSelect(List<Integer> selectId) {
        try {

            String time = DateUtil.dateToString(new Date(), "yyyy-MM-dd");
            for (Integer userId : selectId) {
                // 修改用户表（user）中的用户打卡信息字段（punchInfo）为0
                userMapper.updatePunchInfo(userId,0);
                // 删除打卡信息表（punchinfo）中的打卡信息
                punchInfoMapper.delByIdAndTime(userId, time);
                // 删除打卡表（punchrecord）中的打卡记录
                manageMapper.delPCCById(userId,time);
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.MANAGE_USER_FAIL);
        }

    }

    @Override
    public User getUserById(Integer userId) {
        try {
            return manageMapper.getUserById(userId);
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.MANAGE_USER_FAIL);
        }
    }

    @Transactional
    @Override
    public void delUser(Integer userId) {
        try {
            // 获取该用户所管理的用户，并将其管理者置为空
            List<User> userByCreateId = userMapper.getUserByCreateId(userId);
            for (User user : userByCreateId) {
                userMapper.editSelectsUser(user.getUserId(),"",user.getUpdateTime());
            }

            // 删除该用户的打卡记录
            punchRecordMapper.delPCCByUId(userId);
            // 删除该用户的打卡信息
            punchInfoMapper.delPInfoByUId(userId);
            // 删除该用户的消息
            notifyMapper.delMsgByUId(userId);
            // 删除该用户的需求
            needMapper.delNeedByUId(userId);
            // 删除该用户的行程
            tripInfoMapper.delTripByUId(userId);
            // 删除该用户的解除隔离申请
            recoveredMapper.delRecoveredByUId(userId);

            // 删除该用户
            manageMapper.delById(userId);

        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.MANAGE_USER_FAIL);
        }
    }

    @Override
    public List<PunchRecord> searchPunchPast(PunchRecord punchRecord,User token) {
        try {
            return manageMapper.searchPunchPast(punchRecord,token);
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.PUNCH_PAST__FAIL);
        }
    }

    @Override
    public List<PunchRecord> getPunchPastById(Integer userId) {

        try {
            return manageMapper.getPunchPastById(userId);
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.PUNCH_PAST__FAIL);
        }
    }

    @Override
    public List<PunchRecord> getPunchTable(User token) {
        try {
            List<PunchRecord> punchTable = manageMapper.getPunchTable(token);
            for (PunchRecord punchRecord : punchTable) {
                punchRecord.setPunchInfoNum(manageMapper.getPunchInfoByIdAndTime(punchRecord.getUserId(), punchRecord.getPunchTime()));
            }
            return punchTable;
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.PUNCH_PAST__FAIL);
        }
    }

    @Override
    public List<PunchInfo> getPunchInfoByIdAndTime(Integer userId, String punchTime) {
        try {
            return manageMapper.getPunchInfoByIdAndTime(userId,punchTime);
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.PUNCH_PAST__FAIL);
        }
    }

    @Override
    public List<Need> needAuditing(Integer needState, Integer userId) {
        try {

            User userById = userMapper.getUserById(userId);

            List<Need> needs = null;

            if (needState == 0){

                if (0 == userById.getStatus()){
                    needs = manageMapper.needAuditingManage(needState);
                }else {
                    needs = manageMapper.needAuditing(needState,userId);
                }

            }else {

                if (0 == userById.getStatus()){
                    needs = manageMapper.needAuditingManage1(needState);
                }else {
                    needs = manageMapper.needAuditing1(needState,userId);
                }

            }

            return needs;
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.NEED_FAIL);
        }
    }

    @Override
    public void needAuditingById(Integer needId, Integer needState,String needRemark) {

        try {

            String time = DateUtil.dateToString(new Date(), null);

            manageMapper.needAuditingById(needId,needState,needRemark,time);

        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.NEED_FAIL);
        }

    }

    @Override
    public List<Need> getNeedData(Integer status,Integer userId) {
        try {

            return needMapper.getNeedData(status,userId);

        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.NEED_FAIL);
        }
    }

    @Override
    public List<Need> needSearch(String title, Integer status, String start, String end, User tokenuser) {
        try {

            return needMapper.needSearch(title,status,start,end,tokenuser);

        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.NEED_FAIL);
        }
    }

    @Override
    public void needDataStateUpd(Integer needState,Integer needId) {
        try {

            if (needState != 2){
                needMapper.needDataStateUpd(0,needId);
            }

        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.NEED_FAIL);
        }
    }

    @Override
    public void needDataUpd(Need need) {
        try {

            Need needByneedId = needMapper.getNeedByneedId(need.getNeedId());

            if (!needByneedId.getNeedTitle().equals(need.getNeedTitle()) ||
                    !needByneedId.getNeedValue().equals(need.getNeedValue()) ||
                    !needByneedId.getDelivery().equals(need.getDelivery()) ||
                    !needByneedId.getShippingAddress().equals(need.getShippingAddress())){
                needMapper.needDataUpd(need,needByneedId);
            }

        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.NEED_FAIL);
        }
    }

    @Override
    public List<List<User>> getUserSelectTags(Integer selectedTagUser, Integer selectedTagDoc) {

        try {

            List<List<User>> tagsList = new ArrayList<>();

            List<User> userSelectTags = userMapper.getUserSelectTags(selectedTagUser);
            List<User> docSelectTags = userMapper.getUserSelectTags(selectedTagDoc);

            tagsList.add(userSelectTags);
            tagsList.add(docSelectTags);

            return tagsList;


        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.Notify_FAIL);
        }

    }

    @Override
    public void askSub(Notify notify) {
        try {
            notifyMapper.insertNotify(notify);
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.Notify_FAIL);
        }
    }

    @Override
    public int noPunchUAdd(List<Integer> selectId,Integer loginId) {
        try {
            // 获取当前时间
            String time = DateUtil.dateToString(new Date(), "yyyy-MM-dd");

            // 获取已登陆用户信息
            User userById = userMapper.getUserById(loginId);

            // 已进行未打卡记录的用户数量
            int count = selectId.size();

            for (Integer userId : selectId) {
                // 搜索该用户当日是否已经进行未打卡记录
                PunchRecord punchRecord = punchRecordMapper.selectPRByUIdandTime(userId, time);

                if (punchRecord == null){
                    count--;
                    // 将未打卡用户记录到打卡表（punchrecord）中
                    punchRecordMapper.addPunchRecord(userId,time,"未打卡",userById.getUName() + " : 进行未打卡记录");
                }
            }

            return count;
        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.PUNCH_PAST__FAIL);
        }

    }

    @Transactional
    @Override
    public void editPunchInfoAll() {
        try {

            // 获取当前时间，比较
            LocalTime currentTime = LocalTime.now(); // 获取当前时间
            LocalTime noon = LocalTime.of(12, 0); // 创建当日的12点时间对象

            // 若当日 已过打卡时间（12:00）,则只会重置用户的打卡状态为未打卡，不会删除当日的打卡详情信息
            if (currentTime.isBefore(noon)){

                String time = DateUtil.dateToString(new Date(), "yyyy-MM-dd");
                // 清空今日所有用户 的 打卡记录（punchrecord表）
                punchRecordMapper.delByPunchTime(time);
                // 清空今日所有用户 的 打卡信息（punchinfo表）
                punchInfoMapper.delByCreateTime(time);

            }

            // 修改所有用户的打卡状态
            userMapper.editPunchInfoAll(0);


        }catch (Exception e){
            e.printStackTrace();
            throw new AppException(ResultCode.MANAGE_USER_FAIL);
        }
    }

    @Override
    public void deletePunchInfoAll() {

        // 获取14天前的日期
        LocalDate today = LocalDate.now();
        String date14DaysAgo = today.minusDays(14).toString();

        // System.out.println(date14DaysAgo);

        // 删除14天前的打卡记录
        punchRecordMapper.deletePunchInfoByTime(date14DaysAgo);
        // 删除14天前的打卡信息
        punchInfoMapper.deletePunchInfoByTime(date14DaysAgo);


    }


}
